#include "..\..\NahidaProject-UnitTest\Sources\NahidaUnitTest.h"

#include "..\Sources\CSV.h"
#include "..\Sources\INIReader.h"
#include "..\Sources\INIWriter.h"
#include "..\Sources\JSON.h"
#include "..\Sources\XMLReader.h"
#include "..\Sources\XMLWriter.h"
#include "..\Sources\YAML.h"

TESTCASE(CSVTest) {
	std::ofstream ofs("TestRead.csv", std::ios::out | std::ios::app);
	ofs << R"(a,b,c
1,2,3
4,5,6
7,8,9)" << std::endl;
	ofs.close();

	std::ifstream file("TestRead.csv");
	NahidaProject::CSV::CSV csv(file);

	for (auto& row : csv) {
		for (auto& field : row) {
			std::cout << field << " | ";
		}
		std::cout << "" << std::endl;
	}

	::remove("TestRead.csv");
}

TESTCASE(INIReadAndWriteTest) {
	NahidaProject::INIWriter writer;
	writer.SetFileValue("Section1", "Key1", "Value1");
	writer.SetFileValue("Section1", "Key2", "Value2");
	writer.SetFileValue("Section1", "Key3", "Value3");
	writer.SetFileValue("Section2", "Key1", "Value1");
	writer.SetFileValue("Section2", "Key2", "Value2");
	writer.SetFileValue("Section2", "Key3", "Value3");

	writer.WriteINIFile("TestRead.ini");

	NahidaProject::INIReader reader;
	reader.ReadFile("TestRead.ini");

	JUDGE_EQUAL(reader.GetValue("Section1", "Key1"), "Value1");
	JUDGE_EQUAL(reader.GetValue("Section1", "Key2"), "Value2");
	JUDGE_EQUAL(reader.GetValue("Section1", "Key3"), "Value3");
	JUDGE_EQUAL(reader.GetValue("Section2", "Key1"), "Value1");
	JUDGE_EQUAL(reader.GetValue("Section2", "Key2"), "Value2");
	JUDGE_EQUAL(reader.GetValue("Section2", "Key3"), "Value3");

	::remove("TestRead.ini");
}

TESTCASE(JSONParseTest) {
	NahidaProject::JSON json;
	json.Parse(R"({"name": "Jack", "age": 18, "area": ["c++", "php", "python", "go"], "hobby": {"hobby1": "reading", "hobby2": "coding", "hobby3": "basketball"}})");
	JUDGE_EQUAL(json["name"].ToString(), "\"Jack\"");
	JUDGE_EQUAL(json["age"].ToString(), "18");
	JUDGE_EQUAL(json["area"].ToString(), R"(["c++","php","python","go"])");
	JUDGE_EQUAL(json["hobby"]["hobby1"].ToString(), "\"reading\"");
	JUDGE_EQUAL(json["hobby"]["hobby2"].ToString(), "\"coding\"");
	JUDGE_EQUAL(json["hobby"]["hobby3"].ToString(), "\"basketball\"");

	json.Clear();
}

TESTCASE(XMLReadAndWriteTest) {
	NahidaProject::XMLWriter xmlWriter;
	NahidaProject::XMLWriterNode& documentNode = xmlWriter["DocumentNode"];
	documentNode["Key0"]("Index", "0")("Size", "test");
	documentNode["Key1"]("Index", "1")("Size", "test");
	documentNode["Key2"]("Index", "2")("Size", "test");

	documentNode["Key0"]["AnotherKey"] = "Value0";
	documentNode["Key1"]["AnotherKey"] = "Value1";
	documentNode["Key2"]["AnotherKey"] = "Value2";

	documentNode["Key0"]["AnotherKey"]["Another"]("Attribute0", "Value0") = "Test0";
	documentNode["Key1"]["AnotherKey"]["Another"]("Attribute0", "Value0") = "Test1";

	xmlWriter.OutputFile("TestRead.xml");


	XMLReader::XMLNode xmlNode;
	std::cout << xmlNode.FromFile("TestRead.xml");
	xmlNode.Print();
	XMLReader::XMLNode* node2 = xmlNode.GetChildPtrByName("xml");
	XMLReader::XMLNode* node3 = node2->GetChildPtrByName("DocumentNode");
	XMLReader::XMLNode* node4 = node3->GetChildPtrByName("Key0");
	std::cout << node4->GetAttribute("Index") << std::endl;

	::remove("TestRead.xml");
}

TESTCASE(YAMLTest) {
	std::ofstream ofs("TestRead.yml", std::ios::out | std::ios::app);
	ofs << R"(text: How are you? I am fine Thank you
number: 78.91
boolValue: true
outer_object:
  inner_object:
    name: Ningguang
  name: Ganyu)" << std::endl;
	ofs.close();

	NahidaProject::YAML::YAML yaml("TestRead.yml");
	JUDGE_EQUAL(yaml["text"].cast<std::string>(), "How are you? I am fine Thank you");
	JUDGE_EQUAL(yaml["number"].cast<double>(), 78.91);
	JUDGE_EQUAL(yaml["boolValue"].cast<bool>(), true);
	JUDGE_EQUAL(yaml["outer_object"]["inner_object"]["name"].cast<std::string>(), "Ningguang");
	JUDGE_EQUAL(yaml["outer_object"]["name"].cast<std::string>(), "Ganyu");
	
	::remove("TestRead.yml");
}

int main() {
	NahidaProject::NahidaUnitTest::RunAllTests();
	return 0;
}